package com.stormragetech.arthas.serialize.convertor;

import com.stormragetech.arthas.common.constant.Constant;
import com.stormragetech.arthas.common.exception.ArthasException;
import com.stormragetech.arthas.common.util.Assert;
import lombok.extern.log4j.Log4j2;

import java.lang.reflect.Array;
import java.util.List;

/**
 * description: array convertor, implements interface Convertor
 *
 * @author: Xue Bin
 * @version: 1.0.0-SNAPSHOT
 */
@Log4j2
public class ArrayConvertor<T> implements Convertor {

    private List<String> v;
    private Class<T> c;

    private T target;

    public ArrayConvertor(List<String> v, Class<T> c) throws ArthasException {
        Assert.notNull(v, "the value can not be null !!!");
        Assert.notNull(c, "the target type can not be null !!!");
        this.v = v;
        this.c = c;
        conv();
    }

    @SuppressWarnings("unchecked")
    private void conv() throws ArthasException {
        if (!ConvertProcessor.isArray(c)) {
            throw new ArthasException(Constant.CONV_ERR_CODE, Constant.CONV_NOT_ARRAY, ArthasException.APP_ERR);
        }

        Class<?> type = c.getComponentType();
        int length = v.size();
        Object o = Array.newInstance(type, length);
        for (int i = 0; i < length; i++) {
            if (type.equals(String.class)) {
                Array.set(o, i, v.get(i));
            } else {
                @SuppressWarnings("unchecked")
                Convertor<?> con = new PrimitiveConvertor<>(v.get(i), type);
                Array.set(o, i, con.convert());
            }
        }
        target = (T) o;
    }

    @Override
    public T convert() throws ArthasException {
        return target;
    }
}
